package org.javahispano.javacup.tacticas_aceptadas.rickymoga;


import java.awt.Color;
import java.util.LinkedList;
import org.javahispano.javacup.modelo.*;
import java.util.List;
import java.util.Random;

public class LosJavatos implements Tactica {

    private Posicion posicionBalonAnterior = new Posicion();
    	
    private double distanciaRecorridaBalonEjeX;
    private double distanciaRecorridaBalonEjeY;
    
    Posicion alineacion1[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(23.538461538461537,-26.368778280542987),
        new Posicion(-6.419580419580419,-26.606334841628957),
        new Posicion(7.132867132867133,-25.418552036199095),
        new Posicion(-24.727272727272727,-23.042986425339365),
        new Posicion(-6.419580419580419,-3.088235294117647),
        new Posicion(21.874125874125873,16.628959276018097),
        new Posicion(7.132867132867133,2.3755656108597285),
        new Posicion(3.132867132867133,31.59502262443439),
        new Posicion(-21.16083916083916,16.628959276018097),
        new Posicion(8.55944055944056,33.02036199095023)
    };

    Posicion alineacion2[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(24.965034965034967,-24.705882352941178),
        new Posicion(11.16030534351145,-31.6044776119403),
        new Posicion(-7.132867132867133,-29.694570135746606),
        new Posicion(-29.84732824427481,-26.902985074626866),
        new Posicion(4.5174825174825175,-15.441176470588236),
        new Posicion(17.832167832167833,-3.088235294117647),
        new Posicion(-6.181818181818182,-14.728506787330318),
        new Posicion(-4.9930069930069925,-0.9502262443438915),
        new Posicion(0.4755244755244755,-2.8506787330316743),
        new Posicion(-23.3006993006993,-2.8506787330316743)
    };

    Posicion alineacion3[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(27.104895104895103,-23.755656108597286),
        new Posicion(11.16030534351145,-31.6044776119403),
        new Posicion(-11.412587412587413,-30.88235294117647),
        new Posicion(-29.32824427480916,-21.67910447761194),
        new Posicion(-4.041958041958042,-19.95475113122172),
        new Posicion(20.685314685314687,-3.800904977375566),
        new Posicion(15.454545454545453,-11.877828054298643),
        new Posicion(-7.132867132867133,-8.076923076923077),
        new Posicion(-20.923076923076923,-13.303167420814479),
        new Posicion(6.181818181818182,-9.264705882352942)
    };

    class TacticaDetalleImpl implements TacticaDetalle {

        @Override
        public String getNombre() {
            return "Los Javatos 2009";
        }

        @Override
        public String getPais() {
            return "España";
        }

        @Override
        public String getEntrenador() {
            return "Ricardo Moraleda";
        }

        @Override
        public Color getColorCamiseta() {
            return new Color(42, 7, 98);
        }

        @Override
        public Color getColorPantalon() {
            return new Color(250, 65, 46);
        }

        @Override
        public Color getColorFranja() {
            return new Color(142, 191, 207);
        }

        @Override
        public Color getColorCalcetas() {
            return new Color(102, 211, 42);
        }

        @Override
        public Color getColorPortero() {
            return new Color(140, 163, 60        );
        }

        @Override
        public EstiloUniforme getEstilo() {
            return EstiloUniforme.FRANJA_HORIZONTAL;
        }

        @Override
        public Color getColorCamiseta2() {
            return new Color(248, 107, 52);
        }

        @Override
        public Color getColorPantalon2() {
            return new Color(117, 111, 153);
        }

        @Override
        public Color getColorFranja2() {
            return new Color(133, 162, 227);
        }

        @Override
        public Color getColorCalcetas2() {
            return new Color(86, 92, 232);
        }

        @Override
        public Color getColorPortero2() {
            return new Color(122, 149, 10        );
        }

        @Override
        public EstiloUniforme getEstilo2() {
            return EstiloUniforme.SIN_ESTILO;
        }

        class JugadorImpl implements JugadorDetalle {

            String nombre;
            int numero;
            Color piel, pelo;
            double velocidad, remate, presicion;
            boolean portero;
            Posicion posicion;

            public JugadorImpl(String nombre, int numero, Color piel, Color pelo,
                    double velocidad, double remate, double presicion, boolean portero) {
                this.nombre=nombre;
                this.numero=numero;
                this.piel=piel;
                this.pelo=pelo;
                this.velocidad=velocidad;
                this.remate=remate;
                this.presicion=presicion;
                this.portero=portero;
            }

            @Override
            public String getNombre() {
                return nombre;
            }

            @Override
            public Color getColorPiel() {
                return piel;
            }

            @Override
            public Color getColorPelo() {
                return pelo;
            }

            @Override
            public int getNumero() {
                return numero;
            }

            @Override
            public boolean esPortero() {
                return portero;
            }

            @Override
            public double getVelocidad() {
                return velocidad;
            }

            @Override
            public double getRemate() {
                return remate;
            }

            @Override
            public double getPresicion() {
                return presicion;
            }

        }

        @Override
        public JugadorDetalle[] getJugadores() {
            return new JugadorDetalle[]{
                new JugadorImpl("Westerman", 1, new Color(255,200,150), new Color(50,0,0),0.71d,0.71d,0.0d, true),
                new JugadorImpl("Búfal", 2, new Color(255,200,150), new Color(50,0,0),1.0d,0.5d,0.0d, false),
                new JugadorImpl("Warsman", 3, new Color(255,200,150), new Color(50,0,0),1.0d,0.5d,0.5d, false),
                new JugadorImpl("Blockman", 4, new Color(255,200,150), new Color(50,0,0),1.0d,0.5d,0.5d, false),
                new JugadorImpl("Kamen", 5, new Color(255,200,150), new Color(50,0,0),1.0d,0.82d,0.75d, false),
                new JugadorImpl("Mitsú", 6, new Color(255,200,150), new Color(50,0,0),1.0d,1.0d,1.0d, false),
                new JugadorImpl("Menja-tallarines", 7, new Color(255,200,150), new Color(50,0,0),1.0d,1.0d,1.0d, false),
                new JugadorImpl("Robin", 8, new Color(255,200,150), new Color(50,0,0),1.0d,1.0d,1.0d, false),
                new JugadorImpl("Musculman", 9, new Color(255,200,150), new Color(50,0,0),1.0d,1.0d,1.0d, false),
                new JugadorImpl("Pentagon", 10, new Color(255,200,150), new Color(50,0,0),1.0d,1.0d,1.0d, false),
                new JugadorImpl("Terryman", 11, new Color(255,200,150), new Color(50,0,0),1.0d,1.0d,1.0d, false)
                
            };
        }
    }

    TacticaDetalle detalle=new TacticaDetalleImpl();
    @Override
    public TacticaDetalle getDetalle() {
        return detalle;
    }

    @Override
    public Posicion[] getPosicionSaca(SituacionPartido sp) {
    return alineacion2;
    }

    @Override
    public Posicion[] getPosicionRecive(SituacionPartido sp) {
    return alineacion3;
    }

    Random rand = new Random();
    LinkedList<Comando> comandos = new LinkedList<Comando>();
    
    @Override
    public List<Comando> ejecutar(SituacionPartido sp) {
        
        
        //vacia la lista de comandos
        comandos.clear();
        
        
        //cada jugador ubicarse segun alineacion1
        for (int i = 0; i < 11; i++) {
            comandos.add(new ComandoIrA(i, alineacion1[i]));
        }
        
        //Calcula la posición futura de la bola
        Posicion posBola = new Posicion();
        posBola = calculoPosicionBola(sp.balon());
        
        //movimiento portero
        double porx = Math.max(-3, posBola.getX());
        porx = Math.min(3, porx);
        comandos.add(new ComandoIrA(0, new Posicion(porx,-51.5)));
        
        //portero golpea al frente fuerte y alto
        comandos.add(new ComandoGolpearBalon(0, 90, 1, true));	
        
        // el 9 hace de palomero
        comandos.add(new ComandoIrA(8, Constantes.penalSup));        
     
        int indMasCercano = posBola.indiceMasCercano(sp.misJugadores());
              
        for (int i = 1; i < 11; i++) {
               
            //el jugador mas cercano sigue al balon
            comandos.add(new ComandoIrA(indMasCercano, posBola));
            
            int rematan[] = sp.puedenRematar();
            
            //llevar balón
            comandos.add(new ComandoGolpearBalon(i));
                
            for (int j : rematan) {
                
                //ir a porteria
                comandos.add(new ComandoIrA(j, Constantes.centroArcoSup));
            }
            
            int rivalCercano = sp.misJugadores()[i].indiceMasCercano(sp.rivales());
            if (sp.misJugadores()[i].distancia(sp.rivales()[rivalCercano]) < 15) {
                
                //obtiene los jugadores mas cercanos, al jugador que puede rematar
                int[] cercanos = sp.misJugadores()[i].indicesMasCercanos(sp.misJugadores());
                //encontro un pase en falso
                boolean pase = false;
                boolean alto;
                double fuerte = 1;
                //recorre los jugadores desde el mas lejano al mas cercano
                for (int j = 1; !pase && j < cercanos.length; j++) {
                    //si el jugador es distinto al jugador que remata y el jugador esta mas adelantado
                    if (sp.misJugadores()[i].getY() < sp.misJugadores()[cercanos[j]].getY()) {
                        //dar pase al jugador mas cercano que este en posicion mas ofensiva
                        if (sp.misJugadores()[i].distancia(sp.misJugadores()[cercanos[j]]) > 30) {
                            alto = true;
                            fuerte = 1;
                        } else {
                            alto = false;
                            fuerte = .5 + rand.nextDouble() * .5;
                        }
                        comandos.add(new ComandoGolpearBalon(i, sp.misJugadores()[cercanos[j]], fuerte, alto));
                                                
                        if (posBola.getY() < 10) {
                            comandos.add(new ComandoGolpearBalon(i, sp.misJugadores()[10], fuerte, alto));
                        }
                        
                        
                        //encontro un pase por lo menos
                        pase = true;
                     }
                }
                
                //si no encontro ningun pase adelantado
                if (!pase) {
                    //da pase hacia el jugador mas cercano
                    if (sp.misJugadores()[i].distancia(sp.misJugadores()[cercanos[1]]) > 30) {
                        alto = true;
                    } else {
                        alto = false;
                    }
                    comandos.add(new ComandoGolpearBalon(i, sp.misJugadores()[cercanos[1]], .5 + rand.nextDouble() * .5, alto));
                    
                    
                }
            }    
           
            
            //si el jugador que remata esta a menos de 30 metros del arco rival -> remata al arco
            
            if (sp.misJugadores()[i].distancia(Constantes.centroArcoSup) < 30) {
                comandos.add(new ComandoGolpearBalon(i, new Posicion(Constantes.centroArcoSup.getX(), Constantes.centroArcoSup.getY()), 1, true));
            }

            if (sp.misJugadores()[i].distancia(Constantes.centroArcoSup) < 24) {
                comandos.add(new ComandoGolpearBalon(i, new Posicion(Constantes.centroArcoSup.getX(), Constantes.centroArcoSup.getY()), .5 + rand.nextDouble() * .5, false));
            }

            if (sp.misJugadores()[i].distancia(Constantes.centroArcoSup) < 12) {
                comandos.add(new ComandoGolpearBalon(i, new Posicion(Constantes.centroArcoSup.getX(), Constantes.centroArcoSup.getY()), 1, false));
            }
            
        
        }
        
        //Posicion real de la bola
        this.posicionBalonAnterior = this.posicionBalonAnterior.setPosicion(sp.balon().getX(), sp.balon().getY());
        
        //retorna la lista de comandos.
        return comandos;
    }
    
    
    private Posicion calculoPosicionBola(Posicion bola) {
    	
        this.distanciaRecorridaBalonEjeX = bola.getX() - this.posicionBalonAnterior.getX();
        this.distanciaRecorridaBalonEjeY = bola.getY() - this.posicionBalonAnterior.getY();
        
        //Posición de la bola siguiente iteración. Calculada para saber saber la posición futura de la bola.
        bola = bola.moverPosicion(this.distanciaRecorridaBalonEjeX, this.distanciaRecorridaBalonEjeY);
        
        return bola;
    }

}
